#include <stdio.h> // 引入标准输入输出头文件
#include <string.h> // 引入字符串操作头文件
#include <signal.h> // 引入信号处理头文件
#include <unistd.h> // 引入POSIX操作系统API的头文件

// 信号处理函数，用于处理接收到的信号
void sig_handler(int signum, siginfo_t *info, void *myact) {
    if (signum == SIGINT) { // 如果接收到的是SIGINT信号
        printf("Got a common signal SIGINT\n"); // 打印接收到普通信号的信息
    } else { // 如果接收到的是其他信号（此处特指SIGRTMIN）
        printf("Got a real time signal SIGRTMIN\n"); // 打印接收到实时信号的信息
    }
}

int main(int argc, char **argv) {
    struct sigaction act; // 定义sigaction结构体变量，用于设置信号处理函数
    sigset_t newmask, oldmask; // 定义信号集变量，用于信号屏蔽操作
    int rc;

    sigemptyset(&newmask); // 清空信号集newmask中的所有信号
    sigaddset(&newmask, SIGINT); // 向信号集newmask中添加SIGINT信号
    sigaddset(&newmask, SIGRTMIN); // 向信号集newmask中添加SIGRTMIN信号

    sigprocmask(SIG_BLOCK, &newmask, &oldmask); // 屏蔽SIGINT和SIGRTMIN信号，并将旧的信号屏蔽集保存到oldmask中

    // 设置sigaction结构体变量act，指定信号处理函数为sig_handler，并设置sa_flags为SA_SIGINFO以接收更多信号信息
    act.sa_sigaction = sig_handler;
    act.sa_flags = SA_SIGINFO;

    // 为SIGINT信号设置信号处理函数
    if (sigaction(SIGINT, &act, NULL) < 0) {
        printf("install signal error\n"); // 如果设置失败，则打印错误信息
    }

    // 为SIGRTMIN信号设置信号处理函数
    if (sigaction(SIGRTMIN, &act, NULL) < 0) {
        printf("install signal error\n"); // 如果设置失败，则打印错误信息（注意：原代码中存在语法错误，已修正）
    }

    printf("my process pid = %d\n", getpid()); // 打印当前进程的PID

    // 进程睡眠60秒，在此期间，发给该进程的所有实时信号将排队，信号不会丢失
    sleep(60);

    // 解除SIGINT和SIGRTMIN信号的屏蔽，此时其信号处理函数被调用
    // 对于可靠信号（如实时信号），有几个信号其信号处理函数调用几次
    // 而对于不可靠信号（如SIGINT），只调用一次
    sigprocmask(SIG_SETMASK, &oldmask, NULL);

    return 0; // 程序正常结束
}

